package ar.edu.caece.compiler.grammar.factories;

import ar.edu.caece.compiler.error.ParsingException;
import ar.edu.caece.compiler.grammar.AbstractTokenVisitorFactory;
import ar.edu.caece.compiler.grammar.Recognizer;
import ar.edu.caece.compiler.grammar.TokenRecognizer;
import ar.edu.caece.compiler.grammar.TokenVisitor;
import ar.edu.caece.compiler.grammar.attributes.Attribute;
import ar.edu.caece.compiler.grammar.attributes.AttributeUtils;
import ar.edu.caece.compiler.grammar.attributes.ListaParametrosAttribute;
import ar.edu.caece.compiler.grammar.attributes.tree.NodeLlamadaFuncion;
import ar.edu.caece.compiler.grammar.attributes.tree.NodeParametrosFuncion;
import ar.edu.caece.compiler.grammar.nonterminals.PASOPAM;
import ar.edu.caece.compiler.grammar.nonterminals.POSIBILIDADES3;
import ar.edu.caece.compiler.grammar.terminals.InicioParentesisToken;

public class POSIBILIDADES3Factory extends AbstractTokenVisitorFactory {

	private static POSIBILIDADES3Factory INSTANCE;
	
	private PASOPAMFactory pasopamFactory;
	private TokenVisitor parsePASOPAM;
	
	public static POSIBILIDADES3Factory getInstance() throws Exception {
		if(INSTANCE==null) INSTANCE = new POSIBILIDADES3Factory();
		return INSTANCE;
	}
	
	private Initializer initializer = new Initializer() {
		
		@Override
		public void init() throws Exception {
			initializer = NoOperationInitializer.getInstance();
			pasopamFactory = PASOPAMFactory.getInstance();
			parsePASOPAM = pasopamFactory.makeVisitor();
		}
	};
	
	private POSIBILIDADES3Factory() throws Exception {

	}
	
	@Override
	public TokenVisitor makeChainedVisitor(
			final TokenVisitor siguiente) throws Exception {
		initializer.init();

		return new InicioParentesisToken.InicioParentesisChainVisitor(siguiente) {
			
			@Override
			public Recognizer inicioParentesisCase(InicioParentesisToken llamador) throws Exception {
				parsePASOPAM.addInheretedAttribute(Attribute.TABLA_SIMBOLOS_HEREDADA, getAttribute(Attribute.TABLA_SIMBOLOS_HEREDADA));
				parsePASOPAM.addInheretedAttribute(Attribute.LISTA_PARAMETROS_HEREDADA, new ListaParametrosAttribute());
				
				parsePASOPAM.addInheretedAttribute(Attribute.ARBOL_HEREDADO, new NodeParametrosFuncion() );
				PASOPAM pasopam = (PASOPAM) nextToken().execute(parsePASOPAM);
				POSIBILIDADES3 posibilidades3 = new POSIBILIDADES3(llamador, pasopam);
				
				AttributeUtils.verificarParametros(posibilidades3.getAttribute(Attribute.LEXEMA), pasopam.getAttribute(Attribute.LISTA_PARAMETROS_SINTETIZADA));
				return posibilidades3;
			}
		};
	
	}
	@Override
	public TokenVisitor makeVisitor() throws Exception {
		initializer.init();

		return new InicioParentesisToken.InicioParentesisTokenVisitor() {
			
			@Override
			public Recognizer defaultCase(TokenRecognizer llamador) throws Exception {
				throw new ParsingException("Error de parsing.",POSIBILIDADES3.class,llamador);
			}
			
			@Override
			public Recognizer inicioParentesisCase(InicioParentesisToken llamador) throws Exception {
				
				parsePASOPAM.addInheretedAttribute(Attribute.TABLA_SIMBOLOS_HEREDADA, getAttribute(Attribute.TABLA_SIMBOLOS_HEREDADA));
				parsePASOPAM.addInheretedAttribute(Attribute.LISTA_PARAMETROS_HEREDADA, new ListaParametrosAttribute());
				
				parsePASOPAM.addInheretedAttribute(Attribute.ARBOL_HEREDADO, new NodeParametrosFuncion() );
				PASOPAM pasopam = (PASOPAM) nextToken().execute(parsePASOPAM);
				POSIBILIDADES3 posibilidades3 = new POSIBILIDADES3(llamador, pasopam);
				
				AttributeUtils.verificarParametros(posibilidades3.getAttribute(Attribute.LEXEMA), pasopam.getAttribute(Attribute.LISTA_PARAMETROS_SINTETIZADA));
				return posibilidades3;
			}
		};
	}
	
	
}
